package com.ruoyi.web.controller.procured;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.ruoyi.common.api.procuredOrders.ProcuredOrdersStatusAPi;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.ProcuredOrders;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.depot.domain.Receipt;
import com.ruoyi.depot.service.IReceiptService;
import com.ruoyi.procured.domain.PaymentRequest;
import com.ruoyi.procured.domain.PaymentRequestProcess;
import com.ruoyi.procured.domain.PaymentReturn;
import com.ruoyi.procured.domain.vo.ArrivedQuantityDetailsVO;
import com.ruoyi.procured.domain.vo.OrdersProductDTO;
import com.ruoyi.procured.domain.vo.PaymentRequestLogVo;
import com.ruoyi.procured.domain.vo.ProcuredOrderAmountDTO;
import com.ruoyi.procured.mapper.PaymentRequestMapper;
import com.ruoyi.procured.service.*;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;

import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 采购订单Controller
 * 
 * @author ruoyi
 * @date 2023-11-15
 */
@RestController
@RequestMapping("/product/ProcuredOrders")
public class ProcuredOrdersController extends BaseController
{
    @Autowired
    private IProcuredOrdersService procuredOrdersService;

    //@Autowired
    //private IRequestAdvanceService requestAdvanceService;

    @Autowired
    private IPaymentRequestService paymentRequestService;

    @Autowired
    private IPaymentRequestProcessService paymentRequestProcessService;

    @Autowired
    private PaymentRequestLogService paymentRequestLogService;

    @Autowired
    private PaymentRequestMapper paymentRequestMapper;

    @Autowired
    private IReceiptService receiptService;

    @Autowired
    private ProcuredOrdersStatusAPi procuredOrdersStatusAPi;
    /**
     * 查询采购订单列表
     */
    @PreAuthorize("@ss.hasPermi('product:ProcuredOrders:list')")
    @GetMapping("/list")
    public TableDataInfo list(ProcuredOrders procuredOrders)
    {
        startPage();
        List<ProcuredOrders> list = procuredOrdersService.selectProcuredOrdersList(procuredOrders);
        return getDataTable(list);
    }

    /**
     * 收货页面查看采购订单列表
     */
    @GetMapping("/receipt/list")
    public TableDataInfo receiptProcuredList(ProcuredOrders procuredOrders)
    {
        startPage();
        List<ProcuredOrders> list = procuredOrdersService.selectProcuredOrdersList(procuredOrders);
        return getDataTable(list);
    }

    /**
     * 查询未被收货过的采购订单
     */
    @PreAuthorize("@ss.hasPermi('product:ProcuredOrders:list')")
    @GetMapping("/orders/unreceivedOrders")
    public TableDataInfo ordersList(ProcuredOrders procuredOrders)
    {
        startPage();
        List<ProcuredOrders> list = procuredOrdersService.selectProcuredOrdersList(procuredOrders);
        return getDataTable(list);
    }

    /**
     * 导出采购订单列表
     */
    @PreAuthorize("@ss.hasPermi('product:ProcuredOrders:export')")
    @Log(title = "采购订单", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, ProcuredOrders procuredOrders)
    {
        List<ProcuredOrders> list = procuredOrdersService.selectProcuredOrdersList(procuredOrders);
        ExcelUtil<ProcuredOrders> util = new ExcelUtil<ProcuredOrders>(ProcuredOrders.class);
        util.exportExcel(response, list, "采购订单数据");
    }

    /**
     * 获取采购订单详细信息
     */
    @PreAuthorize("@ss.hasPermi('product:ProcuredOrders:query')")
    @GetMapping(value = "/{ordersId}")
    public AjaxResult getInfo(@PathVariable("ordersId") Long ordersId)
    {
        return success(procuredOrdersService.selectProcuredOrdersByOrdersId(ordersId));
    }

    /**
     * 查询库存待到货量详细
     * @param vo
     * @return
     */
    @PreAuthorize("@ss.hasPermi('product:ProcuredOrders:query')")
    @GetMapping(value = "/product/getArrivedQuantityDetails")
    public TableDataInfo getArrivedQuantityDetails(ArrivedQuantityDetailsVO vo)
    {
        startPage();
        return getDataTable(procuredOrdersService.getArrivedQuantityDetails(vo));
    }

    /**
     * 新增采购订单
     */
    @PreAuthorize("@ss.hasPermi('product:ProcuredOrders:add')")
    @Log(title = "采购订单", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody ProcuredOrders procuredOrders)
    {
        return toAjax(procuredOrdersService.insertProcuredOrders(procuredOrders));
    }

    /**
     * 修改采购订单
     */
    @PreAuthorize("@ss.hasPermi('product:ProcuredOrders:edit')")
    @Log(title = "采购订单", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody ProcuredOrders procuredOrders)
    {
        return toAjax(procuredOrdersService.updateProcuredOrders(procuredOrders));
    }

    /**
     * 删除采购订单
     */
    @PreAuthorize("@ss.hasPermi('product:ProcuredOrders:remove')")
    @Log(title = "采购订单", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ordersIds}")
    public AjaxResult remove(@PathVariable Long[] ordersIds)
    {
        return toAjax(procuredOrdersService.deleteProcuredOrdersByOrdersIds(ordersIds));
    }

//    /**
//     * 申请预付款
//     * @param requestAdvance
//     * @return
//     */
//    @PreAuthorize("@ss.hasPermi('product:RequestAdvance:add')")
//    @Log(title = "申请预付款", businessType = BusinessType.INSERT)
//    @PostMapping("/insertRequestAdvance")
//    public AjaxResult insertRequestAdvance(@RequestBody RequestAdvance requestAdvance){
//        requestAdvance.setApplicant(getNickname());
//        requestAdvance.setApplicationDate(DateUtils.getNowDate());
//        return toAjax(requestAdvanceService.insertRequestAdvance(requestAdvance));
//    }
//
//    /**
//     * 申请应付款
//     * @param requestAdvance
//     * @return
//     */
//    @PreAuthorize("@ss.hasPermi('product:RequestAdvance:add')")
//    @Log(title = "申请应付款", businessType = BusinessType.INSERT)
//    @PostMapping("/insertRequestAdvanceQuash")
//    public AjaxResult insertRequestAdvanceQuash(@RequestBody RequestAdvance requestAdvance){
//        requestAdvance.setApplicant(getNickname());
//        requestAdvance.setApplicationDate(DateUtils.getNowDate());
//        return toAjax(requestAdvanceService.insertRequestAdvanceQuash(requestAdvance));
//    }
//
//
//    /**
//     * 查询该采购下所申请的记录数据
//     * @param requestAdvance
//     * @return
//     */
//    @PreAuthorize("@ss.hasPermi('product:RequestAdvance:list')")
//    @GetMapping("/selectRequestAdvanceList")
//    public TableDataInfo selectRequestAdvanceList(RequestAdvance requestAdvance){
//        startPage();
//        List<RequestAdvance> requestAdvances = requestAdvanceService.selectRequestAdvanceList(requestAdvance);
//        return getDataTable(requestAdvances);
//    }
//
//    /**
//     * 取消申请
//     * @param requestIds
//     * @return
//     */
//    @PreAuthorize("@ss.hasPermi('product:RequestAdvance:cancel')")
//    @PutMapping("/requestAdvanceByRequestId/{requestIds}")
//    public AjaxResult requestAdvanceByRequestId(@PathVariable Long[] requestIds){
//        return toAjax(requestAdvanceService.deleteRequestAdvanceByRequestIds(requestIds));
//    }
//
//    /**
//     * 最大可申请多少钱
//     * @param ordersId
//     * @return
//     */
//    @PreAuthorize("@ss.hasPermi('product:RequestAdvance:cancel')")
//    @GetMapping("/selectTotalAmountDue/{ordersId}")
//    public AjaxResult selectTotalAmountDue(@PathVariable Long ordersId){
//        return success(requestAdvanceService.selectTotalAmountDue(ordersId));
//    }

    @PreAuthorize("@ss.hasPermi('product:ProcuredOrders:list')")
    @PutMapping("/updateInboundNumber/{ordersId}")
    public AjaxResult updateInboundNumber(@PathVariable Long ordersId){
        return success(procuredOrdersService.updateInboundNumber(ordersId));
    }

    /**
     * 添加跟踪记录
     * @param procuredOrders
     * @return
     */
    @PutMapping("/updateExpressNumber")
    public AjaxResult updateExpressNumber(@RequestBody ProcuredOrders procuredOrders){
        return toAjax(procuredOrdersService.updateExpressNumber(procuredOrders));
    }


    /**
     * 查询可申请的付款
     * @param ordersId
     * @return
     */
    @GetMapping("/selectProcuredOrderAmountDueById/{ordersId}")
    public ProcuredOrderAmountDTO selectProcuredOrderAmountDueById(@PathVariable String ordersId){
        return paymentRequestService.selectProcuredOrderAmountDueById(ordersId);
    }

    /**
     * 申请付款
     * @param paymentRequest
     * @return
     */
    @PreAuthorize("@ss.hasPermi('product:PaymentRequest:add')")
    @Log(title = "申请付款", businessType = BusinessType.INSERT)
    @PostMapping("/insertPaymentRequestQuash")
    public AjaxResult insertPaymentRequestQuash(@RequestBody PaymentRequest paymentRequest,
                                                @RequestParam("procuredOrderId") String procuredOrderId,
                                                @RequestParam("componentPath") String componentPath){

        if(StringUtils.isEmpty(paymentRequest.getPaymentType())){
            throw new RuntimeException("申请付款方式为空，请联系管理员核查。");
        }
        if(StringUtils.isNull(procuredOrderId)){
            throw new RuntimeException("关联的采购订单ID为空，请联系管理员核查。");
        }

        //查询可申请的付款
        ProcuredOrderAmountDTO ato = selectProcuredOrderAmountDueById(procuredOrderId);
        BigDecimal amountDue = ato.getTotalAmountDue();
        paymentRequest.setApplicant(getNickname());
        //【申请付款方式】（0预付款，1应付款）
        String paymentMethod = paymentRequest.getPaymentType();
        if(paymentMethod.equals(Constants.PAYMENT_METHOD_ZERO)){
            BigDecimal prepaymentAmount = paymentRequest.getPrepaymentAmount();
            if(StringUtils.isNull(prepaymentAmount)){
                throw new RuntimeException("预付金额为空，请填写预付金额。");
            }
            if((prepaymentAmount.compareTo(amountDue))>0){
                throw new RuntimeException("【最大可申请金额】已发生变化,请关闭当前页面，重新申请付款。");
            }
            paymentRequest.setPayableAmount(null);
            paymentRequest.setOtherFeeType(null);
            paymentRequest.setOtherFeeAmount(null);
            paymentRequest.setOtherFeeRemark(null);
        }else{
            if(StringUtils.isNotEmpty(paymentRequest.getOtherFeeType())){
                if(StringUtils.isNull(paymentRequest.getOtherFeeAmount())){
                    throw new RuntimeException("【其他费用】费用金额不能为空，请填写金额。");
                }
                if(StringUtils.isNull(paymentRequest.getOtherFeeRemark())){
                    throw new RuntimeException("【其他费用】费用备注不能为空，请填写备注。");
                }
            }
            paymentRequest.setPayableAmount(amountDue);
            paymentRequest.setPrepaymentCycle(null);
            paymentRequest.setPrepaymentAmount(null);
            paymentRequest.setPrepaymentRemark(null);
        }

        if(StringUtils.isNotEmpty(paymentRequest.getOtherFeeType())){
            BigDecimal otherFeeAmount = paymentRequest.getOtherFeeAmount();
            if(paymentRequest.getOtherFeeType().equals("减少")){
                paymentRequest.setOtherFeeAmount(otherFeeAmount.negate());
            }
        }

       return toAjax(paymentRequestService.insertPaymentRequestQuash(paymentRequest,procuredOrderId,getUserId(),componentPath));
    }

    /**
     * 查询该采购下所申请的记录数据
     * @param paymentRequest
     * @return
     */
    @PreAuthorize("@ss.hasPermi('product:PaymentRequest:list')")
    @GetMapping("/selectPaymentRequestList")
    public TableDataInfo selectPaymentRequestList(PaymentRequest paymentRequest){
        startPage();
        List<PaymentRequest> paymentRequests = paymentRequestService.selectPaymentRequestList(paymentRequest);
        return getDataTable(paymentRequests);
    }

    /**
     * 取消申请
     * @param paymentRequestIds
     * @return
     */
    @PreAuthorize("@ss.hasPermi('product:PaymentRequest:cancel')")
    @PutMapping("/setCancelPaymentRequestByIds/{paymentRequestIds}")
    public AjaxResult setCancelPaymentRequestByIds(@PathVariable List<String> paymentRequestIds){
        String nickname = getNickname();
        if (CollectionUtils.isEmpty(paymentRequestIds)) {
            throw new IllegalArgumentException("paymentRequestIds 不能为空");
        }
        return toAjax(paymentRequestService.setCancelPaymentRequestByIds(paymentRequestIds, nickname));
    }

    /**
     * 批量申请付款
     * @param ordersIds
     * @return
     */
    @PreAuthorize("@ss.hasPermi('product:PaymentRequest:add')")
    @Log(title = "批量申请付款", businessType = BusinessType.INSERT)
    @PostMapping("/insertBatchPaymentRequestQuash/{ordersIds}")
    public AjaxResult insertBatchPaymentRequestQuash(@PathVariable String ordersIds,@RequestParam("componentPath") String componentPath){
        String[] idsArray = ordersIds.split(","); // 按逗号分割
        List<String> orderIdList = Arrays.stream(idsArray)
                .map(String::valueOf) // 转换为 Long
                .collect(Collectors.toList());

        if (ordersIds == null || ordersIds.isEmpty()) {
            throw new IllegalArgumentException("采购订单ID不能为空");
        }

        orderIdList.forEach(ordersId ->{
            //查询可申请的付款
            ProcuredOrderAmountDTO ato = selectProcuredOrderAmountDueById(ordersId);
            BigDecimal amountDue = ato.getTotalAmountDue();
            if(amountDue.compareTo(BigDecimal.ZERO)<=0){
                System.out.println("订单 " + ordersId + " 的应付金额小于等于 0，跳过当前订单。");
                return;
            }
            PaymentRequest paymentRequest =  new PaymentRequest();
            paymentRequest.setPaymentType("1");
            paymentRequest.setApplicant(getNickname());
            paymentRequest.setPayableAmount(amountDue);

            paymentRequestService.insertPaymentRequestQuash(paymentRequest,ordersId,getUserId(),componentPath);
        });

        return success();
    }

    /**
     * 查询审核记录
     * @return
     */
    @PreAuthorize("@ss.hasPermi('product:PaymentRequest:list')")
    @GetMapping("/selectPaymentRequestByStatus")
    public TableDataInfo selectPaymentRequestByStatus(@RequestParam(required = false) Long reviewStatus, @RequestParam(required = false)  Long deptId,
                                                   @RequestParam(required = false) Long userId,@RequestParam(required = false) String applicant){
        startPage();
        return getDataTable(paymentRequestService.selectPaymentRequestByStatus(reviewStatus,deptId,userId,applicant));
    }

    /**
     * 查询审核流程
     * @param paymentRequestId
     * @return
     */
    @PreAuthorize("@ss.hasPermi('product:PaymentRequestProcess:list')")
    @GetMapping("/selectPaymentRequestProcessList/{paymentRequestId}")
    public AjaxResult selectPaymentRequestProcessList(@PathVariable String paymentRequestId){
        return success(paymentRequestProcessService.selectPaymentRequestProcessList(paymentRequestId));
    }

    /**
     * 更新审核流程状态
     * @param paymentRequestProcess
     * @return
     */
    @PostMapping("/updateProcessStatus")
    public AjaxResult updateProcessStatus(@RequestBody PaymentRequestProcess paymentRequestProcess){
        return toAjax(paymentRequestProcessService.updateProcessStatus(paymentRequestProcess));
    }

    /**
     * 查询该申请的所有审核记录数据
     * @param paymentRequestLog
     * @return
     */
    @GetMapping("/selectPaymentRequestLogList")
    public TableDataInfo selectPaymentRequestLogList(PaymentRequestLogVo paymentRequestLog){
        startPage();
        List<PaymentRequestLogVo> paymentRequestLogs = paymentRequestLogService.selectPaymentRequestLogList(paymentRequestLog);
        return getDataTable(paymentRequestLogs);
    }

    /**
     * 申请退款
     * @param paymentRequest
     * @return
     */
    @PreAuthorize("@ss.hasPermi('product:PaymentRequest:add')")
    @Log(title = "申请付款", businessType = BusinessType.INSERT)
    @PostMapping("/insertPaymentReturnQuash")
    public AjaxResult insertPaymentReturnQuash(@RequestBody PaymentRequest paymentRequest,
                                                @RequestParam("procuredOrderId") String procuredOrderId,
                                                @RequestParam("componentPath") String componentPath){

        if(StringUtils.isEmpty(paymentRequest.getPaymentType())){
            throw new RuntimeException("申请退款【退款方式】不能为空");
        }
        if(StringUtils.isNull(procuredOrderId)){
            throw new RuntimeException("关联的采购订单ID为空，请联系管理员核查");
        }
        if(StringUtils.isEmpty(paymentRequest.getReturnRemark())){
            throw new RuntimeException("申请退款【退款备注】不能为空");
        }

        BigDecimal returnAmount = paymentRequest.getReturnAmount();
        if(returnAmount == null){
            throw new RuntimeException("申请退款【退款金额】不能为空");
        }
        //查询可申请的付款
        ProcuredOrderAmountDTO ato = selectProcuredOrderAmountDueById(procuredOrderId);
        BigDecimal maxReturnAmount = ato.getMaxRefundAmount();
        paymentRequest.setApplicant(getNickname());

        if((returnAmount.compareTo(maxReturnAmount))>0){
                throw new RuntimeException("【最大可申请金额】已发生变化,请关闭当前页面，重新申请退款");
        }

        List<PaymentReturn> items = paymentRequest.getItems();
        if (items == null || items.isEmpty()) {
            throw new IllegalArgumentException("Items不能为空");
        }
        items.stream().forEach(item -> {
            if (item.getQuantity() == null || item.getQuantity() < 0) {
                throw new IllegalArgumentException("数量不能为空或小于0");
            }
            if (item.getSku() == null || item.getSku().isEmpty()) {
                throw new IllegalArgumentException("SKU不能为空");
            }
            if (item.getProductId() == null || item.getProductId().isEmpty()) {
                throw new IllegalArgumentException("产品ID不能为空");
            }
        });

        return toAjax(paymentRequestService.insertPaymentReturnQuash(paymentRequest,procuredOrderId,getUserId(),componentPath));
    }

    /**
     * 查询该申请的采购订单数据（商品信息，入库，出库信息）
     * @param ordersId
     * @return
     */
    @GetMapping("/getOrdersProductList/{ordersId}")
    public TableDataInfo getOrdersProductList(@PathVariable("ordersId") Long ordersId){
        startPage();
        List<OrdersProductDTO> ordersProductDTO = procuredOrdersService.selectOrdersProductListByOrdersId(ordersId);
        return getDataTable(ordersProductDTO);
    }

    /**
     * 撤回采购单订单
     * @return
     */
    @PreAuthorize("@ss.hasPermi('product:ProcuredOrders:edit')")
    @Log(title = "撤回采购单订单", businessType = BusinessType.INSERT)
    @PostMapping("/revokeProcuredOrders")
    public AjaxResult revokeProcuredOrders(@RequestParam("procuredOrderId") Long procuredOrderId,
                                               @RequestParam("revokeRemark") String revokeRemark){

        if(StringUtils.isNull(procuredOrderId)){
            throw new RuntimeException("关联的采购订单ID为空，请联系管理员核查");
        }
        if(StringUtils.isEmpty(revokeRemark)){
            throw new RuntimeException("撤回采购单订单【备注】不能为空");
        }

        ProcuredOrders  procuredOrders = procuredOrdersService.selectProcuredOrdersByOrdersId(procuredOrderId);
        if(procuredOrders == null){
            throw new RuntimeException("获取采购订单失败");
        }
        BigDecimal totalRequestedAmount =  paymentRequestMapper.sumAmountByProcuredOrderId(procuredOrderId);
        if (totalRequestedAmount != null && totalRequestedAmount.compareTo(BigDecimal.ZERO) > 0) {
            // 大于0的情况
            throw new RuntimeException("采购订单已存在【申请付款】记录，无法撤回采购订单");
        }
        boolean hasReceipt = receiptService.lambdaQuery()
                .eq(Receipt::getOrdersId, procuredOrderId)
                .exists();

        if (hasReceipt) {
            throw new RuntimeException("采购订单已存在【收货】记录，无法撤回采购订单");
        }

        return toAjax(procuredOrdersService.revokeProcuredOrders(procuredOrderId,revokeRemark,getNickname()));
    }

    /**
     * 驳回标记处理
     * @param paymentRequestId
     * @return
     */
    @PreAuthorize("@ss.hasPermi('product:PaymentRequest:solve')")
    @PostMapping("/setSolvePaymentRequestByIds")
    public AjaxResult setSolvePaymentRequestByIds(@RequestParam("paymentRequestId") String paymentRequestId){

        if(StringUtils.isNull(paymentRequestId)){
            throw new RuntimeException("关联的采购订单ID为空，请联系管理员核查。");
        }
        PaymentRequest existingRequest = paymentRequestMapper.selectById(paymentRequestId);
        if(existingRequest == null) {
            return AjaxResult.error("未找到对应的申请驳回记录");
        }
        //更新退款单状态
        procuredOrdersStatusAPi.setProcuredOrderStatus(Long.valueOf(existingRequest.getProcuredOrderId()));
        existingRequest.setSolveStatus("1");
        paymentRequestMapper.updateById(existingRequest);
        return success();
    }
}
